<?php

namespace addons\shopro\controller;

use addons\epay\library\Service;
use fast\Random;
use think\addons\Controller;
use addons\shopro\exception\Exception;
use addons\shopro\model\Order;
use addons\shopro\model\User;
use addons\shopro\model\TradeOrder;
use think\Db;
use think\Log;

class Pay extends Base
{

    protected $noNeedLogin = ['prepay', 'notifyx', 'notifyr', 'alipay','notifyx_zijie','notifyxkuaishou'];
    protected $noNeedRight = ['*'];


    /**
     * 支付宝网页支付
     */
    public function alipay()
    {
        $order_sn = $this->request->get('order_sn');

        list($order, $prepay_type) = $this->getOrderInstance($order_sn);
        $order = $order->where('order_sn', $order_sn)->find();

        try {
            if (!$order) {
                throw new \Exception("订单不存在");
            }
            if ($order->status > 0) {
                throw new \Exception("订单已支付");
            }
            if ($order->status < 0) {
                throw new \Exception("订单已失效");
            }
    
            $notify_url = $this->request->root(true) . '/addons/shopro/pay/notifyx/payment/alipay/platform/H5';
            $pay = new \addons\shopro\library\PayService('alipay', 'url', $notify_url);
    
            $order_data = [
                'order_id' => $order->id,
                'out_trade_no' => $order->order_sn,
                'total_fee' => $order->total_fee,
                'subject' => '商城订单支付',
            ];
    
            $result = $pay->create($order_data);

            $result = $result->getContent();
            
	        echo $result;
        } catch (\Exception $e) {
            echo $e->getMessage();
        }

        // $this->assign('result', $result);

        // return $this->view->fetch();
    }


    /**
     * 拉起支付
     */
    public function prepay()
    {
        checkEnv('yansongda');

        $order_sn = $this->request->post('order_sn');
        $payment = $this->request->post('payment');
        $openid = $this->request->post('openid', '');
        $platform = request()->header('platform');

        list($order, $prepay_type) = $this->getOrderInstance($order_sn);
        $order = $order->nopay()->where('order_sn', $order_sn)->find();

        if (!$order) {
            $this->error("订单不存在");
        }

        if (!$payment || !in_array($payment, ['wechat', 'alipay', 'wallet','zijie','kuaishou'])) {
            $this->error("支付类型不能为空");
        }

        if ($payment == 'wallet' && $prepay_type == 'order') {
            // 余额支付
            $this->walletPay($order, $payment, $platform);
        }

        if ($payment == 'kuaishou'){

            //开始-2022-3-19 Ripple 快手小程序担保支付处理
            if (empty($openid)){
                $this->error('openid缺失');
            }
            $order_data = [
                'order_sn' => $order->order_sn,
                'total_fee' => $order->total_fee,
                'openid' => $openid,
            ];
            $result = $this->kuaishou_create_order($order_data);
            if (!$result['result']){
                $this->error('支付参数获取失败',$result);
            }
            return $this->success('获取预付款成功', [
                'pay_data' => $result['data'],
                'pay_action' => 'miniapp',
            ]);
            //结束-2022-3-19 Ripple 快手小程序担保支付处理

        }else if ($payment == 'zijie'){

            //开始-2022-2-8 Ripple 抖音小程序担保支付处理
            $order_data = [
                'order_sn' => $order->order_sn,
                'total_fee' => $order->total_fee,
            ];
            $result = $this->zijie_create_order($order_data);
            if (empty($result) || ($result['err_no'] != 0)){
                $this->error('支付参数获取失败',$result);
            }
            return $this->success('获取预付款成功', [
                'pay_data' => $result,
                'pay_action' => 'miniapp',
            ]);
            //结束-2022-2-8 Ripple 抖音小程序担保支付处理

        }else{//老代码

            $order_data = [
                'order_id' => $order->id,
                'out_trade_no' => $order->order_sn,
                'total_fee' => $order->total_fee,
            ];

            // 微信公众号，小程序支付，必须有 openid
            if ($payment == 'wechat') {
                if (in_array($platform, ['wxOfficialAccount', 'wxMiniProgram'])) {
                    if (isset($openid) && $openid) {
                        // 如果传的有 openid
                        $order_data['openid'] = $openid;
                    } else {
                        // 没有 openid 默认拿下单人的 openid
                        $oauth = \addons\shopro\model\UserOauth::where([
                            'user_id' => $order->user_id,
                            'provider' => 'Wechat',
                            'platform' => $platform
                        ])->find();

                        $order_data['openid'] = $oauth ? $oauth->openid : '';
                    }

                    if (empty($order_data['openid'])) {
                        // 缺少 openid
                        return $this->success('缺少 openid', 'no_openid');
                    }
                }

                $order_data['body'] = '商城订单支付';
            } else {
                $order_data['subject'] = '商城订单支付';
            }

            $notify_url = $this->request->root(true) . '/addons/shopro/pay/notifyx/payment/' . $payment . '/platform/' . $platform;
            $pay = new \addons\shopro\library\PayService($payment, $platform, $notify_url);

            try {
                $result = $pay->create($order_data);
            } catch (\Yansongda\Pay\Exceptions\Exception $e) {
                $this->error("支付配置错误：" . $e->getMessage());
            }

            if ($platform == 'App') {
                $result = $result->getContent();
            }
            if ($platform == 'H5' && $payment == 'wechat') {
                $result = $result->getContent();
            }

            return $this->success('获取预付款成功', [
                'pay_data' => $result,
                'pay_action' => $pay->method,
            ]);

        }

    }



    // 余额支付
    public function walletPay ($order, $type, $method) {
        $order = Db::transaction(function () use ($order, $type, $method) {
            // 重新加锁读，防止连点问题
            $order = Order::nopay()->where('order_sn', $order->order_sn)->lock(true)->find();
            if (!$order) {
                $this->error("订单已支付");
            }
            $total_fee = $order->total_fee;

            // 扣除余额
            $user = User::info();

            if (is_null($user)) {
                // 没有登录，请登录
                $this->error(__('Please login first'), null, 401);
            }

            User::money(-$total_fee, $user->id, 'wallet_pay', $order->id, '',[
                'order_id' => $order->id,
                'order_sn' => $order->order_sn,
            ],'xt','');

            // 支付后流程
            $notify = [
                'order_sn' => $order['order_sn'],
                'transaction_id' => '',
                'notify_time' => date('Y-m-d H:i:s'),
                'buyer_email' => $user->id,
                'pay_fee' => $order->total_fee,
                'pay_type' => 'wallet'             // 支付方式
            ];
            $notify['payment_json'] = json_encode($notify);
            $order->paymentProcess($order, $notify);

            return $order;
        });

        $this->success('支付成功', $order);
    }


    /**
     * 支付成功回调
     */
    public function notifyx()
    {
        Log::write('notifyx-comein:');

        $payment = $this->request->param('payment');
        $platform = $this->request->param('platform');

        $pay = new \addons\shopro\library\PayService($payment, $platform);

        $result = $pay->notify(function ($data, $pay) use ($payment, $platform) {
            Log::write('notifyx-result:'. json_encode($data));
            // {    // 微信回调参数
            //     "appid":"wx39cd0799d4567dd0",
            //     "bank_type":"OTHERS",
            //     "cash_fee":"1",
            //     "fee_type":"CNY",
            //     "is_subscribe":"N",
            //     "mch_id":"1481069012",
            //     "nonce_str":"dPpcZ6AzCDU8daNC",
            //     "openid":"oD9ko4x7QMDQPZEuN8V5jtZjie3g",
            //     "out_trade_no":"202010240834057843002700",
            //     "result_code":"SUCCESS",
            //     "return_code":"SUCCESS",
            //     "sign":"3103B6D06F13D2B3959C5B3F7F1FD61C",
            //     "time_end":"20200407102424",
            //     "total_fee":"1",
            //     "trade_type":"JSAPI",
            //     "transaction_id":"4200000479202004070804485027"
            // }

            // {    // 支付宝支付成功回调参数
            //     "gmt_create":"2020-04-10 19:15:00",
            //     "charset":"utf-8",
            //     "seller_email":"xptech@qq.com",
            //     "subject":"\u5546\u57ce\u8ba2\u5355\u652f\u4ed8",
            //     "sign":"AOiYZ1a2mEMOuIbHFCi6V6A0LJ97UMiHsCWgNdSU9dlzKFl15Ts8b0mL\/tN+Hhskl+94S3OUiNTBD3dD0Kv923SqaTWxNdj533PCdo2GDKsZIZgKbavnOvaccSKUdmQRE9KtmePPq9V9lFzEQvdUkKq1M8KAWO5K9LTy2iT2y5CUynpiu\/04GVzsTL9PqY+LDwqj6K+w7MgceWm1BWaFWg27AXIRw7wvsFckr3k9GGajgE2fufhoCYGYtGFbhGOp6ExtqS5RXBuPODOyRhBLpD8mwpOX38Oy0X+R4YQIrOi02dhqwPpvw79YjnvgXY3qZEQ66EdUsrT7EBdcPHK0Gw==",
            //     "buyer_id":"2088902485164146",
            //     "invoice_amount":"0.01",
            //     "notify_id":"2020041000222191501064141414240102",
            //     "fund_bill_list":"[{\"amount\":\"0.01\",\"fundChannel\":\"PCREDIT\"}]",
            //     "notify_type":"trade_status_sync",
            //     "trade_status":"TRADE_SUCCESS",
            //     "receipt_amount":"0.01",
            //     "buyer_pay_amount":"0.01",
            //     "app_id":"2021001114666742",
            //     "sign_type":"RSA2",
            //     "seller_id":"2088721922277739",
            //     "gmt_payment":"2020-04-10 19:15:00",
            //     "notify_time":"2020-04-10 19:15:01",
            //     "version":"1.0",
            //     "out_trade_no":"202007144778322770017000",
            //     "total_amount":"0.01",
            //     "trade_no":"2020041022001464141443020240",
            //     "auth_app_id":"2021001114666742",
            //     "buyer_logon_id":"157***@163.com",
            //     "point_amount":"0.00"
            // }

            // {   // 支付宝退款成功（交易关闭）回调参数
            //     "gmt_create": "2020-08-15 14:48:32",
            //     "charset": "utf-8",
            //     "seller_email": "xptech@qq.com",
            //     "gmt_payment": "2020-08-15 14:48:32",
            //     "notify_time": "2020-08-15 16:11:45",
            //     "subject": "商城订单支付",
            //     "gmt_refund": "2020-08-15 16:11:45.140",
            //     "sign": "b6ArkgzLIRteRL9FMGC6i\/jf6VwFYQbaGDGRx002W+pdmN5q9+O4edZ3ALF74fYaijSl9ksNr0dKdvanu3uYxBTcd\/GIS4N1CWzmCOv6pzgx5rO\/YvGoHLM3Yop0GKKuMxmnNsZ6jhYKEY7SYD3Y0L6PU9ZMdHV7yIiVj+zZmbKzUgK9MPDCEXs+nzpNAiSM8GTqYRSUvKobAK68hswG2k1QIcqr5z+ZmVYa\/nHHkoC9qXt5zwyGi4P+2eOsr6V2PjA3x8qqe7TN5aI1DeoZD5KqHPYYaYF17J2q6YPlgl3WUl1RhE7H86bivB1fIuYEv\/3+JR74WN\/o7krGw1RPHg==",
            //     "out_biz_no": "R202004114414846255015300",
            //     "buyer_id": "2088902485164146",
            //     "version": "1.0",
            //     "notify_id": "2020081500222161145064141453349793",
            //     "notify_type": "trade_status_sync",
            //     "out_trade_no": "202002460317545607015300",
            //     "total_amount": "0.01",
            //     "trade_status": "TRADE_CLOSED",
            //     "refund_fee": "0.01",
            //     "trade_no": "2020081522001464141438570535",
            //     "auth_app_id": "2021001114666742",
            //     "buyer_logon_id": "157***@163.com",
            //     "gmt_close": "2020-08-15 16:11:45",
            //     "app_id": "2021001114666742",
            //     "sign_type": "RSA2",
            //     "seller_id": "2088721922277739"
            // }

            try {
                $out_trade_no = $data['out_trade_no'];
                $out_refund_no = $data['out_biz_no'] ?? '';

                list($order, $prepay_type) = $this->getOrderInstance($out_trade_no);
                
                // 判断是否是支付宝退款（支付宝退款成功会通知该接口）
                if ($payment == 'alipay'    // 支付宝支付
                    && $data['notify_type'] == 'trade_status_sync'      // 同步交易状态
                    && $data['trade_status'] == 'TRADE_CLOSED'          // 交易关闭
                    && $out_refund_no                                   // 退款单号
                ) {
                    // 退款回调
                    if ($prepay_type == 'order') {
                        // 退款回调
                        $this->refundFinish($out_trade_no, $out_refund_no);
                    } else {
                        // 其他订单如果支持退款，逻辑这里补充
                    }

                    return $pay->success()->send();
                }


                // 判断支付宝微信是否是支付成功状态，如果不是，直接返回响应
                if ($payment == 'alipay' && $data['trade_status'] != 'TRADE_SUCCESS') {
                    // 不是交易成功的通知，直接返回成功
                    return $pay->success()->send();
                }
                if ($payment == 'wechat' && ($data['result_code'] != 'SUCCESS' || $data['return_code'] != 'SUCCESS')) {
                    // 微信交易未成功，返回 false，让微信再次通知
                    return false;
                }

                // 支付成功流程
                $pay_fee = $payment == 'alipay' ? $data['total_amount'] : $data['total_fee'] / 100;

                //你可以在此编写订单逻辑
                $order = $order->where('order_sn', $out_trade_no)->find();

                if (!$order || $order->status > 0) {
                    // 订单不存在，或者订单已支付
                    return $pay->success()->send();
                }

                Db::transaction(function () use ($order, $data, $payment, $platform, $pay_fee, $prepay_type) {
                    $notify = [
                        'order_sn' => $data['out_trade_no'],
                        'transaction_id' => $payment == 'alipay' ? $data['trade_no'] : $data['transaction_id'],
                        'notify_time' => date('Y-m-d H:i:s', strtotime($data['time_end'])),
                        'buyer_email' => $payment == 'alipay' ? $data['buyer_logon_id'] : $data['openid'],
                        'payment_json' => json_encode($data->all()),
                        'pay_fee' => $pay_fee,
                        'pay_type' => $payment              // 支付方式
                    ];
                    $order->paymentProcess($order, $notify);
                });

                return $pay->success()->send();
            } catch (\Exception $e) {
                Log::write('notifyx-error:' . json_encode($e->getMessage()));
            }
        });

        return $result;
    }

    /**
     * 抖音小程序支付成功回调、退款成功回调
     * @author Ripple
     */
    public function notifyx_zijie(){
        # 接受参数处理
        $post_str = file_get_contents('php://input');
        $post_str = $post_str ? : $_GET;
        if (!empty($post_str) && is_string($post_str)){
            $post_arr =  json_decode($post_str,true);
        }elseif(is_array($post_str)){
            $post_arr = $post_str;
        }else{
            $post_arr = [];
        }
        //有回调参数
        if (!empty($post_arr)){
            if ($post_arr['type'] == 'payment'){//支付成功
                $post_msg_str = str_replace('&quot;','"',$post_arr['msg']);
                $post_msg_arr = json_decode($post_msg_str,true);
                $cp_orderno = $post_msg_arr['cp_orderno'];//订单编号
                $way = $post_msg_arr['way'];//支付渠道：2-支付宝，1-微信

                //处理验证签名参数
                $sign_arr = [];
                foreach ($post_arr as $key => $val) {
                    if (empty($val) || $key == 'msg_signature' || $key == 'type') {
                        continue;
                    }
                    $sign_arr[$key] = $val;
                }
                //获取抖音小程序配置
                $ziJie = Db::name('shopro_config')->where(['name'=>'ziJieMiniProgram','group'=>'platform'])->value('value');
                $ziJie_array = json_decode($ziJie,true);
                $token = isset($ziJie_array['token']) ? $ziJie_array['token']:'';
                //验证签名
                $notify_sign = zijie_notify_sign($sign_arr,$token);
                if ($notify_sign == $post_arr['msg_signature']){//签名一致

                    //你可以在此编写订单逻辑
                    $order = new Order();
                    $order = $order->where('order_sn', $cp_orderno)->find();

                    if ($order->status == 0){
                        Db::transaction(function () use ($order,$cp_orderno, $post_arr, $way) {
                            $notify = [
                                'transaction_id' => $cp_orderno,
                                'payment_json' => json_encode($post_arr),
                                'pay_fee' => $order['total_fee'],
                                'pay_type' => ($way == 1)? 'wechat':'alipay',
                            ];
                            $order->paymentProcess($order, $notify);
                        });
                    }
                }
            }

            if ($post_arr['type'] == 'refund'){//退款成功

                $post_msg_str = str_replace('&quot;','"',$post_arr['msg']);
                $post_msg_arr = json_decode($post_msg_str,true);
                $cp_refundno = $post_msg_arr['cp_refundno'];//开发者自定义的退款单号
                $cp_extra = $post_msg_arr['cp_extra'];//开发者传的额外参数,请求时传的什么返回什么。退款时后台传的订单编号

                //处理验证签名参数
                $sign_arr = [];
                foreach ($post_arr as $key => $val) {
                    if (empty($val) || $key == 'msg_signature' || $key == 'type') {
                        continue;
                    }
                    $sign_arr[$key] = $val;
                }
                //获取抖音小程序配置
                $ziJie = Db::name('shopro_config')->where(['name'=>'ziJieMiniProgram','group'=>'platform'])->value('value');
                $ziJie_array = json_decode($ziJie,true);
                $token = isset($ziJie_array['token']) ? $ziJie_array['token']:'';
                //验证签名
                $notify_sign = zijie_notify_sign($sign_arr,$token);
                if ($notify_sign == $post_arr['msg_signature']){//签名一致
                    // 退款
                    $this->refundFinish($cp_extra, $cp_refundno);
                }
            }

            die(json_encode(['err_no'=>0,'err_tips'=>"success"]));
        }

    }

    /**
     * 快手小程序支付成功回调、退款成功回调
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function notifyxkuaishou(){
        //获取抖音小程序配置
        $kuaiShou = Db::name('shopro_config')->where(['name'=>'kuaiShouMiniProgram','group'=>'platform'])->value('value');
        $kuaiShou_array = json_decode($kuaiShou,true);
        $appid = isset($kuaiShou_array['appid']) ? $kuaiShou_array['appid']:'';
        $secret = isset($kuaiShou_array['secret']) ? $kuaiShou_array['secret']:'';

        # 接受参数处理
        $post_str = file_get_contents('php://input');
        $post_str = $post_str ? : $_GET;
        if (!empty($post_str) && is_string($post_str)){
            $post_arr =  json_decode($post_str,true);
        }elseif(is_array($post_str)){
            $post_arr = $post_str;
        }else{
            $post_arr = [];
        }

        $kwaisign = $this->request->header('kwaisign');

        //有回调参数
        if (!empty($post_arr)){
            if ($post_arr['biz_type'] == 'PAYMENT'){//支付成功

                $post_data = $post_arr['data'];
                if ($post_data['channel'] == 'WECHAT'){//支付渠道-微信
                    $way = 1;
                }else{//支付渠道-支付宝
                    $way = 2;
                }
                $out_order_no = $post_data['out_order_no'];//订单编号
                $status = $post_data['status'];//订单支付状态。 取值： PROCESSING-处理中｜SUCCESS-成功｜FAILED-失败

                //生成签名
                $post_arr_string = json_encode($post_arr);
                $sign = md5($post_arr_string.$secret);

                //签名一致 且 支付成功
                if (($sign == $kwaisign) && ($status == 'SUCCESS')){

                    //你可以在此编写订单逻辑
                    $order = new Order();
                    $order = $order->where('order_sn', $out_order_no)->find();

                    if ($order->status == 0){

                        Db::transaction(function () use ($order,$out_order_no, $post_arr, $way) {
                            $notify = [
                                'transaction_id' => $post_arr['data']['trade_no'],
                                'payment_json' => json_encode($post_arr),
                                'pay_fee' => $order['total_fee'],
                                'pay_type' => ($way == 1)? 'wechat':'alipay',
                            ];
                            $order->paymentProcess($order, $notify);
                        });
                    }
                }
            }

            if ($post_arr['biz_type'] == 'REFUND'){//退款成功

                $post_data = $post_arr['data'];
                $out_refund_no = $post_data['out_refund_no'];//退款单号
                $attach = $post_data[''];//预下单时携带的开发者自定义信息。退款时后台传的订单编号
                $status = $post_data['status'];//订单支付状态。 取值： PROCESSING-处理中，SUCCESS-成功，FAILED-失败

                //生成签名
                $post_arr_string = json_encode($post_arr);
                $sign = md5($post_arr_string,$secret);

                //签名一致 且 退款成功
                if (($sign == $kwaisign) && ($status == 'SUCCESS')){
                    // 退款
                    $this->refundFinish($attach, $out_refund_no);
                }

            }

            die(json_encode(['result'=>1,'message_id'=>$post_arr['message_id']]));
        }
    }

    /**
     * 退款成功回调
     */
    public function notifyr()
    {
        Log::write('notifyreturn-comein:');

        $payment = $this->request->param('payment');
        $platform = $this->request->param('platform');

        $pay = new \addons\shopro\library\PayService($payment, $platform);

        $result = $pay->notifyRefund(function ($data, $pay) use ($payment, $platform) {
            Log::write('notifyr-result:' . json_encode($data));
            try {
                $out_refund_no = $data['out_refund_no'];
                $out_trade_no = $data['out_trade_no'];

                // 退款
                $this->refundFinish($out_trade_no, $out_refund_no);
                
                return $pay->success()->send();
            } catch (\Exception $e) {
                Log::write('notifyreturn-error:' . json_encode($e->getMessage()));
            }
        });

        return $result;
    }

    
    private function refundFinish($out_trade_no, $out_refund_no) {
        $order = Order::where('order_sn', $out_trade_no)->find();
        $refundLog = \app\admin\model\shopro\order\RefundLog::where('refund_sn', $out_refund_no)->find();

        if (!$order || !$refundLog || $refundLog->status != 0) {
            // 订单不存在，或者订单已退款
            return true;
        }

        $item = \app\admin\model\shopro\order\OrderItem::where('id', $refundLog->order_item_id)->find();

        Db::transaction(function () use ($order, $item, $refundLog) {
            \app\admin\model\shopro\order\Order::refundFinish($order, $item, $refundLog);
        });

        return true;
    }


    /**
     * 根据订单号获取订单实例
     *
     * @param [type] $order_sn
     * @return void
     */
    private function getOrderInstance($order_sn) 
    {
        $prepay_type = 'order';
        if (strpos($order_sn, 'TO') === 0) {
            // 充值订单
            $prepay_type = 'recharge';
            $order = new TradeOrder();
        } else {
            // 订单
            $order = new Order();
        }

        return [$order, $prepay_type];
    }


    /**
     * 字节-服务端预下单
     * @param array $order
     * @author Ripple
     * @return mixed
     */
    private function zijie_create_order($order = []){
        /*$order = [
            'order_sn' => '',//订单编号
            'total_fee' => 0,//订单金额（分）
        ];*/

        //获取抖音小程序配置
        $ziJie = Db::name('shopro_config')->where(['name'=>'ziJieMiniProgram','group'=>'platform'])->value('value');
        $ziJie_array = json_decode($ziJie,true);
        $appid = isset($ziJie_array['appid']) ? $ziJie_array['appid']:'';
        $salt = isset($ziJie_array['salt']) ? $ziJie_array['salt']:'';

        $baseUrl = 'https://developer.toutiao.com/api/apps/ecpay/v1/create_order';
        $param_data = [
            'app_id' => $appid,//小程序APPID
            'out_order_no' => $order['order_sn'],//订单编号
            'total_amount' => $order['total_fee'] * 100,//支付金额（分）
            'subject' => '商城订单支付',//商品描述
            'body' => '商城订单支付',//商品详情
            'valid_time' => 24 * 60 * 60,//订单过期时间（S）
            'sign' => '',//签名
            //'cp_extra' => '',//开发者自定义字段，回调原样回传
            'notify_url' => $this->request->root(true) . '/addons/shopro/pay/notifyx_zijie',//回调地址
            //'thirdparty_id' => '',//第三方平台服务商 id，非服务商模式留空
            'disable_msg' => 1,//是否屏蔽担保支付的推送消息，1-屏蔽 0-非屏蔽，接入 POI 必传
            //'msg_page' => '',//担保支付消息跳转页
        ];
        $param_data['sign'] = zijie_param_sign($param_data,$salt);
        //请求
        $result = curlPost($baseUrl,json_encode($param_data),['Content-Type: application/json']);

        return json_decode($result,true);
    }

    /**
     * 快手-服务端预下单
     * @param array $order
     * @return array
     */
    private function kuaishou_create_order($order = []){
        /*$order = [
         'order_sn' => '',//订单编号
         'total_fee' => 0,//订单金额（分）,
         'openid' => '',//用户openid
        ];*/

        $result = [
            'result' => true,//结果
            'error_msg' => '',//错误提示语
            'error_data' => '',//错误数据
            'data' => '',//正确数据
        ];

        //获取快手小程序配置
        $kuaiShou = Db::name('shopro_config')->where(['name'=>'kuaiShouMiniProgram','group'=>'platform'])->value('value');
        $kuaiShou_array = json_decode($kuaiShou,true);
        $appid = isset($kuaiShou_array['appid']) ? $kuaiShou_array['appid']:'';
        $secret = isset($kuaiShou_array['secret']) ? $kuaiShou_array['secret']:'';

        //获取access_token
        $access_token = cache('kuaishou_access_token');
        if (empty($access_token)){
            $get_token_url = 'https://open.kuaishou.com/oauth2/access_token';
            $get_token_param = [
                'app_id' => $appid,
                'app_secret' => $secret,
                'grant_type' => 'client_credentials',
            ];
            //请求
            $get_token_result = curlPost($get_token_url,http_build_query($get_token_param),['Content-Type: application/x-www-form-urlencoded']);
            //判断数据
            $get_token_result_array = json_decode($get_token_result,true);
            if (!(isset($get_token_result_array['result']) && ($get_token_result_array['result'] == 1))){
                $result['result'] = false;
                $result['error_msg'] = '获取access_token失败';
                $result['error_data'] = $get_token_result_array;
                return $result;
            }
            $access_token = $get_token_result_array['access_token'];
            cache('kuaishou_access_token',$access_token,47*60*60);
        }


        $baseUrl = 'https://open.kuaishou.com/openapi/mp/developer/epay/create_order?app_id=' . $appid . '&access_token=' . $access_token;

        $param_data = [
            'out_order_no' => $order['order_sn'],//订单编号
            'open_id' => $order['openid'],//快手用户在当前小程序的open_id
            'total_amount' => $order['total_fee'] * 100,//支付金额（分）
            'subject' => '商城订单支付',//商品描述
            'detail' => '商城订单支付',//商品详情
            'type' => 2294,//商品类型
            'expire_time' => 24 * 60 * 60,//订单过期时间，单位秒
            'sign' => '',//开发者对核心字段签名
            'notify_url' => $this->request->root(true) . '/addons/shopro/pay/notifyxkuaishou',//回调地址
        ];
        $param_data['sign'] = kuaishou_param_sign($param_data,['app_id'=>$appid],$secret);
        //请求
        $pay_result = curlPost($baseUrl,json_encode($param_data),['Content-Type: application/json']);

        $pay_result_array = json_decode($pay_result,true);
        if (!(isset($pay_result_array['result']) && ($pay_result_array['result'] == 1))){
            $result['result'] = false;
            $result['error_msg'] = '获取支付参数失败';
            $result['error_data'] = $pay_result_array;
            return $result;
        }else{
            $result['data'] = $pay_result_array['order_info'];
            return $result;
        }
    }
}
